﻿

using com.youzu.got.protocol;
using System;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Gameplay.RTS.Proto;
using CastSkill = com.youzu.warh.protocol.CastSkill;
namespace Yoozoo.Gameplay.RTS
{
    public class Skill
    {
        private int _skillId;
        private int _heroId;
        private long _skillTargetId;
        private float _startPlayTime;
        private float _endTime;
        private THeroSkill _config;
        public MarchEntity March;
        private bool _uiPlayed;
        private int _heroSkillIndex;
        private float _skillStartTime;
        private List<int> skillIds = new List<int>(4);
        private float _skill_hit_light;
        private bool isPlayHighLight = false;
        private ERtsSkillState _status;
        private bool _isRelatedToSelf;
        private List<int> skillEffects = new List<int>(4);
        private bool needChangeEffectColor;
        private float targetHitEffectStartTime = -1;
        private GameObject hitEffectObj;
        internal void Initialize(CastSkill skill, int heroSkillIndex, MarchEntity marchEntity, float startTime)
        {
            _skillId = skill.skillId;
            _heroId = skill.heroId;
            _skillTargetId = skill.target.uid;
            _startPlayTime = startTime;
            _endTime = startTime + 6;
            var config = ArmyManager.Instance.ResourceManager.GetHeroSkillConfig(skill.skillId, skill.skillLv);
            _config = config;
            March = marchEntity;
            _uiPlayed = false;
            _heroSkillIndex = heroSkillIndex;
            needChangeEffectColor = _skillId == RoundFightPlayer.DEFAULT_SUB_SKILL_ID;
            var skill_EffectId = config.skill_effect_id;
            if (skill_EffectId != null && skill_EffectId.Count > 0)
            {
                _skillStartTime = startTime + skill_EffectId[0].y;
            }
            else
            {
                _skillStartTime = startTime;
            }

            if (skill_EffectId!=null)
            {
                for (int i = 0; i < skill_EffectId.Count; i++)
                {
                    skillIds.Add((int)skill_EffectId[i].x);
                }
            }

            

            _skill_hit_light = config.skill_hit_light / 1000f;

            isPlayHighLight = false;

            _status = ERtsSkillState.NotPlay;
            var target = marchEntity.GetBattleTarget();
            _isRelatedToSelf = marchEntity.Team == MarchHelper.TeamSelf || target?.Team == MarchHelper.TeamSelf; 
        }

        public bool CheckIsSame(int skillId,int skillLv)
        {
            if (skillId == RoundFightPlayer.NORMAL_ATTACK_SKILL_ID)
            {
                return skillId == _skillId;
            }
            else
            {
                return skillId == _config.id && skillLv == _config.skill_level;
            }
        }

        private void PlayUI(MarchEntity march,MarchEntity target)
        {
            _uiPlayed = true;

            if (!MarchHelper.ShowRtsSkillEffect())
            {
                return;
            }
            
            if (target != null)
            {
                bool playFocusEffect = false;
                for (int i = 0; i < skillIds.Count; i++)
                {
                    var skillId = skillIds[i];
                    var dic = RTSBattleEffectManager.Instance.GetEffectConfigs(skillId);
                    if (dic!=null && dic.Count > 0)
                    {
                        foreach (var effectConfig in dic.Values)
                        {
                            if (effectConfig.bind_target == 0)
                            {
                                playFocusEffect = true;
                            }
                        }
                    }
                }
                if (_config.type == 2 && target.MarchInfo.IsInBattleState && playFocusEffect)
                {
                    ArmyManager.Instance.ElementManager.ShowSkillFocusEffect(target.Tid,target.TargetCoordinateType);
                }
            }
            
            if (march!=null)
            {
                var monsterSkillIcon = string.Empty;
                if (march.ClientMarchType == EClientMarchType.Monster)
                {
                    var heroList = march.MarchInfo.HeroList;
                    if (heroList!= null && heroList.Count > 0)
                    {
                        var monsterId = heroList[0];
                        var heroConfig = ArmyManager.Instance.ResourceManager.GetHeroMonsterConig(monsterId);
                        if (heroConfig != null)
                        {
                            monsterSkillIcon = heroConfig.rts_skill_spell;
                        }
                    }
                }
                if (_config.type == 2 && march.MarchInfo.IsInBattleState)
                {
                    if (target!=null && target.MarchInfo.MarchType != MarchType.DIE_5)
                    {
                        ArmyManager.Instance.ElementManager.ShowReleaseSkillEffect(march.Tid,march.TargetCoordinateType, _heroId, ArmyManager.Instance.ResourceManager.GetLangConfigTxt(_config.skill_name), _heroSkillIndex, monsterSkillIcon);
                    }
                }
            }
        }

        public void Play()
        {
            _status = ERtsSkillState.Playing;
        }
        public void Update(float curTime)
        {
            if (curTime > _endTime)
            {
                _status = ERtsSkillState.End;
                return;
            }
            var target = March.GetBattleTarget();
            if (_status == ERtsSkillState.NotPlay)
            {
                if (!_uiPlayed && curTime >= _startPlayTime)
                {
                    PlayUI(March, target);
                    _status = ERtsSkillState.Playing;
                    ShowDirector();
                    PlaySkillAnimation();
                }
            }

            if (MarchHelper.ShowRtsSkillEffect())
            {
                CheckSkill(curTime, target);

                if (curTime - _startPlayTime - _skill_hit_light > 0 && _skill_hit_light > 0 && !isPlayHighLight)
                {
                    if (target != null && target.MarchInfo.IsInBattleState && !target.IsWaitDelete && target.MarchInfo.MarchType != MarchType.DIE_5)
                    {
                        ArmyManager.Instance.ElementManager.ShowSkillHitEffect(target.Tid,target.TargetCoordinateType,March.Team);
                        var effect = RTSLuaCallCSharpManager.GetEffectById(1015, _isRelatedToSelf);
                        if (effect != null)
                        {
                            effect.SetActive(false);
                            effect.SetActive(true);
                            effect.transform.position = target.Position;
                            hitEffectObj = effect;
                            targetHitEffectStartTime = curTime;
                        }
                    }
                    isPlayHighLight = true;
                }
            }
            
            if (targetHitEffectStartTime != -1 && curTime - targetHitEffectStartTime >= 2)
            {
                targetHitEffectStartTime = -1;
                RTSLuaCallCSharpManager.RecoverEffectById(1015, hitEffectObj);
                hitEffectObj = null;
            }
        }

        private void PlaySkillAnimation()
        {
            if (March?.RtsServerInfo != null && (March.RtsServerInfo.Type == TargetCoordinateType.ALLIANCE_PRACTICE_BOSS_32 || March.RtsServerInfo.Type == TargetCoordinateType.DONALD_BOSS_38 || March.RtsServerInfo.Type == TargetCoordinateType.WORLD_BOSS_44))
            {
                if (!string.IsNullOrEmpty(_config.skill_animation))
                {
                    March.PlaySkillAnimation(_config.skill_animation);
                }
                if (_config.animation_change_speed.x > 0)
                {
                    March.SetAttackAnimationSpeed(_config.animation_change_speed.x, _config.animation_change_speed.y);
                }
            }
        }

        private void ShowDirector()
        {
            if (!MarchHelper.ShowRtsSkillEffect())
            {
                return;
            }
            if (March.GetBattleTarget() == null)
            {
                return;
            }

            for (int i = 1; i < 3; i++)
            {
                if (CheckChildSkillDirector(i))
                {
                    break;
                }
            }
        }

        private bool CheckChildSkillDirector(int i)
        {
            List<int> element;
            Dictionary<string, float> child_director_parmData;
            List<int> targetType;

            if (i == 1)
            {
                element = _config.child1_element;
                child_director_parmData = _config.child1_director_parmData;
                targetType = _config.child1_target_type;
            }
            else if (i == 2)
            {
                element = _config.child2_element;
                child_director_parmData = _config.child2_director_parmData;
                targetType = _config.child2_target_type;
            }
            else
            {
                element = _config.child3_element;
                child_director_parmData = _config.child3_director_parmData;
                targetType = _config.child2_target_type;
            }

            if (element != null && element.Count > 0 && child_director_parmData != null && child_director_parmData.Count > 0 && March.RtsServerInfo.Type != TargetCoordinateType.DEFENSE_ASSEMBLY_29)
            {
                var target = March.GetBattleTarget();
                if (target != null && targetType != null)
                {
                    if (March.MarchInfo.IsInBattleState && !target.IsWaitDelete && target.MarchInfo.MarchType != MarchType.DIE_5 && targetType.Count >= 3)
                    {
                        RTSLuaCallCSharpManager.ShowSkillDirector(March.Team, targetType[0], targetType[1], targetType[2], child_director_parmData, March.Position, March.GetBattleTarget().Position, 1);
                        return true;
                    }
                }
                return false;
            }
            return false;
        }

        private void CheckSkill(float curTime, MarchEntity target)
        {
            if (target == null)
            {
                return;
            }
            for (int i = 0; i < _config.skill_effect_id.Count; i++)
            {
                var vector2 = _config.skill_effect_id[i];
                if (skillIds[i] > 0 && curTime - vector2.y / 1000 - _startPlayTime >= 0)
                {
                    long targetId = 0;
                    if (target != null)
                    {
                        targetId = target.Tid;
                    }
                    if (targetId == 0)
                    {
                        targetId = _skillTargetId;
                    }
                    bool isInBuild = March.MarchInfo.BuildingUid != 0 && March.MarchInfo.TargetType != TargetCoordinateType.CARGO_TRUCK_42;
                    if (!isInBuild && 
                        March.MarchInfo.IsInBattleState && 
                        !March.IsWaitDelete && March.MarchInfo.MarchType != MarchType.DIE_5 && 
                        March.RtsServerInfo.Type != TargetCoordinateType.DEFENSE_ASSEMBLY_29 && 
                        March.RtsServerInfo.Type != TargetCoordinateType.DEFENCE_ASSEMBLY_NPC_23)
                    {
                        if (!target.IsWaitDelete && target.MarchInfo.MarchType != MarchType.DIE_5)
                        {
                            var effect = RTSLuaCallCSharpManager.PlayEffectAndSound(skillIds[i], March.Tid,March.TargetCoordinateType ,targetId,target.TargetCoordinateType ,_isRelatedToSelf, March.Team,_config.audio, "sfx_rts_skillfreed",needChangeEffectColor);
                            skillEffects.Add(effect);
                            skillIds[i] = -1;
                        }
                    }
                }
            }
        }

        public float GetStartTime()
        {
            return _skillStartTime;
        }

        public float GetHitTime()
        {
            return _skillStartTime;
        }

        public bool IsEnd()
        {
            return _status == ERtsSkillState.End;
        }

        public void Dispose()
        {
            _status = ERtsSkillState.End;
            foreach (var effectId in skillEffects)
            {
                if (effectId >= 0)
                {
                    RTSLuaCallCSharpManager.RemoveEffect(effectId, _isRelatedToSelf);
                }
            }
            targetHitEffectStartTime = -1;

            if (hitEffectObj!=null)
            {
                RTSLuaCallCSharpManager.RecoverEffectById(1015, hitEffectObj);
                hitEffectObj = null;
            }
            skillEffects.Clear();
            skillIds.Clear();
            _startPlayTime = 0;
            _endTime = 0;
            _config = null;
            March = null;
        }
        internal void OnReset()
        {
            
        }

       
    }
}
